import os
import sys

import pandas as pd
import warnings
import cv2

warnings.filterwarnings("ignore")

root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(root)

from main_v2 import tools
import numpy as np
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from glob import glob

outputs = os.path.join(root, "outputs")
datasets = os.path.join(root, "datasets")

funcs = {
    "entropy": tools.entropy,  # 熵函数
    "EAV": tools.EAV,  # EAV点锐度算法函数
    "SMD": tools.SMD,  # SMD（灰度方差）函数
    "SMD2": tools.SMD2,  # SMD2 （灰度方差乘积）函数
    "variance": tools.variance,  # 方差函数
    "tenengrad": tools.tenengrad,  # Tenengrad 梯度函数
    "tenengrad2": tools.tenengrad2,  # Tenengrad2 原项目实现的Tenengrad 梯度函数
    "vollath": tools.vollath,  # Vollath函数
    "laplacian": tools.laplacian,  # Laplacian 梯度函数
    "brenner": tools.brenner,  # Brenner 梯度函数
    "nrss": tools.nrss,  # NRSS 梯度结构相似度
    "energy": tools.energy,  # 能量梯度函数
    "NR_IQA": tools.NR_IQA,  # No-Reference Image Quality Assessment  using Blur and Noise
    "JPEQ": tools.JPEQ,  # No-Reference Perceptual Quality Assessment of JPEG Compressed Images
    "JPEQ2": tools.JPEQ2  # No-Reference Image Quality Assessment forJPEG/JPEG2000 Coding
}


def sigmoid(data):
    return 1.0 / (1 + np.exp(-data))


def min_max(data):
    return (data - np.min(data)) / (np.max(data) - np.min(data))


def map_min_max(data, xmin=20.0, xmax=80.0, f=1.0):
    map_min, map_max = (0.0, 1.0)
    data = np.array(list(map(lambda x: x + f if x <= xmin else x, data)))
    data = np.array(list(map(lambda x: x - f if x >= xmax else x, data)))
    data = map_min + (map_max - map_min) / (xmax - xmin) * (data - xmin)
    return data


def load_csv():
    csv_data = pd.read_csv(os.path.join(outputs, "blur_test_iqa_.csv"))
    images_list = os.path.join(datasets, "blur", "images_list.txt")

    label = []
    with open(images_list, "r") as op:
        for line in op.readlines():
            line = line.split()[-1]
            label.append(int(line))

    label = np.array(label)

    return csv_data, label


def entropy(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------熵函数------------------------------------------------")
    prefix = "entropy"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
            precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
            f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=3.5, xmax=4, f=0.1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def EAV(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------EAV------------------------------------------------")
    prefix = "EAV"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=0.01, xmax=0.7, f=0.05)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def SMD(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------SMD------------------------------------------------")
    prefix = "SMD"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=6.2, xmax=66, f=0.5)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def SMD2(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------SMD2------------------------------------------------")
    prefix = "SMD2"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=13.2, xmax=1120, f=1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def variance(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------variance------------------------------------------------")
    prefix = "variance"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=400, xmax=3600, f=1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def tenengrad(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------tenengrad------------------------------------------------")
    prefix = "tenengrad"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=20, xmax=200, f=1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def tenengrad2(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------tenengrad2------------------------------------------------")
    prefix = "tenengrad2"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=20, xmax=80, f=1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def vollath(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------vollath------------------------------------------------")
    prefix = "vollath"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin= -1700, xmax=1400, f=100)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def laplacian(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------laplacian------------------------------------------------")
    prefix = "laplacian"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=7, xmax=99, f=1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def brenner(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------brenner------------------------------------------------")
    prefix = "brenner"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=39, xmax=5990, f=1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def nrss(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------nrss------------------------------------------------")
    prefix = "nrss"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=0.85, xmax=1.0, f=0.05)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def energy(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------energy------------------------------------------------")
    prefix = "energy"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=49, xmax=6100, f=1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def NR_IQA(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------NR_IQA------------------------------------------------")
    prefix = "NR_IQA"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=-11, xmax=-5, f=-0.5)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def JPEQ(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------JPEQ------------------------------------------------")
    prefix = "JPEQ"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=9.5, xmax=15, f=0.1)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def JPEQ2(csv_data, label, min_l=0.1, max_l=0.9, nums=9):
    print("----------------------------------------JPEQ2------------------------------------------------")
    prefix = "JPEQ2"
    data = csv_data[[prefix, "{}_{}".format(prefix, "time")]]

    val = data[prefix].values
    time = data["{}_{}".format(prefix, "time")].values

    print("+++++++++++++info++++++++++++++++++")
    print("min: {:.4f}, max: {:.4f}, mean: {:.4f}, std: {:.4f}".format(np.min(val), np.max(val), np.mean(val),
                                                                       np.std(val)))

    print("+++++++++++++sigmoid++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = sigmoid(val - np.mean(val))
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = min_max(val)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++map min max++++++++++++++++++")
    res = {}
    for th in np.linspace(min_l, max_l, nums):
        sigmoid_val = map_min_max(val, xmin=4.900, xmax=4.999, f=0.01)
        sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
        res[th] = (
        precision_score(label, sigmoid_val), recall_score(label, sigmoid_val), accuracy_score(label, sigmoid_val),
        f1_score(label, sigmoid_val))

    res = sorted(res.items(), key=lambda x: x[1][-1])
    max_res = res[-1]
    print("th: {}, precision: {:.4f}, recall {:.4f}, accuracy: {:.4f}, f1: {:.4f}".format(max_res[0], *max_res[1]))

    print("+++++++++++++avg time++++++++++++++++++")
    print("avg time: {:.4f}".format(np.mean(time)))


def max_index2csv():
    params = {
        "entropy": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 3.5, "xmax": 4, "f": 0.1},  # 熵函数
        "EAV": {"min_l":0.01,"max_l":0.99,"nums":99,"xmin":0.01,"xmax":0.7,"f":0.05},  # EAV点锐度算法函数
        "SMD": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 6.2, "xmax": 66, "f": 0.5},  # SMD（灰度方差）函数
        "SMD2": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 13.2, "xmax": 1120, "f": 1},  # SMD2 （灰度方差乘积）函数
        "variance": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 400, "xmax": 3600, "f": 1},  # 方差函数
        "tenengrad": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 20, "xmax": 200, "f": 1},  # Tenengrad 梯度函数
        "tenengrad2": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 20, "xmax": 80, "f": 1},
        # Tenengrad2 原项目实现的Tenengrad 梯度函数
        "vollath": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 430, "xmax": 1400, "f": 1},  # Vollath函数
        "laplacian": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 7, "xmax": 99, "f": 1},  # Laplacian 梯度函数
        "brenner": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 39, "xmax": 5990, "f": 1},  # Brenner 梯度函数
        "nrss": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 0.85, "xmax": 1.0, "f": 0.05},  # NRSS 梯度结构相似度
        "energy": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 49, "xmax": 6100, "f": 1},  # 能量梯度函数
        # "NR_IQA": {"min_l":0.01,"max_l":0.99,"nums":99,"xmin":-7,"xmax":-4,"f":0.5},  # No-Reference Image Quality Assessment  using Blur and Noise
        # "JPEQ": {"min_l":0.01,"max_l":0.99,"nums":99,"xmin":10,"xmax":12,"f":0.5},  # No-Reference Perceptual Quality Assessment of JPEG Compressed Images
        # "JPEQ2": {"min_l":0.01,"max_l":0.99,"nums":99,"xmin":4.998,"xmax":4.999,"f":0.001}  # No-Reference Image Quality Assessment forJPEG/JPEG2000 Coding
    }

    with open(os.path.join(root, "outputs", "max_index_iqa.csv"), "w") as op:
        op.write(
            "funcs,min,max,mean,std,avg_time,"
            "sig_th,sig_p,sig_r,sig_a,sig_f1,"
            "mm_th,mm_p,mm_r,mm_a,mm_f1,"
            "mmm_th,mmm_p,mmm_r,mmm_a,mmm_f1\n")
        for key, value in params.items():
            csv_data, label = load_csv()
            data = csv_data[[key, "{}_{}".format(key, "time")]]

            val = data[key].values
            time = data["{}_{}".format(key, "time")].values

            line = ""
            line+="{},{:.4f},{:.4f},{:.4f},{:.4f},{:.4f},".format(key,np.min(val),np.max(val),np.mean(val),np.std(val),np.mean(time))

            res = {}
            for th in np.linspace(value["min_l"], value["max_l"], value["nums"]):
                sigmoid_val = sigmoid(val - np.mean(val))
                sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
                res[th] = (
                    precision_score(label, sigmoid_val), recall_score(label, sigmoid_val),
                    accuracy_score(label, sigmoid_val),
                    f1_score(label, sigmoid_val))

            res = sorted(res.items(), key=lambda x: x[1][-1])
            max_res = res[-1]

            line+="{:.2f},{:.4f},{:.4f},{:.4f},{:.4f},".format(max_res[0],*max_res[1])

            res = {}
            for th in np.linspace(value["min_l"], value["max_l"], value["nums"]):
                sigmoid_val = min_max(val)
                sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
                res[th] = (
                    precision_score(label, sigmoid_val), recall_score(label, sigmoid_val),
                    accuracy_score(label, sigmoid_val),
                    f1_score(label, sigmoid_val))

            res = sorted(res.items(), key=lambda x: x[1][-1])
            max_res = res[-1]
            line+="{:.2f},{:.4f},{:.4f},{:.4f},{:.4f},".format(max_res[0],*max_res[1])

            res = {}
            for th in np.linspace(value["min_l"], value["max_l"], value["nums"]):
                sigmoid_val = map_min_max(val, xmin=value["xmin"], xmax=value["xmax"], f=value["f"])
                sigmoid_val = np.array(list(map(lambda x: 0 if x > th else 1, sigmoid_val)))
                res[th] = (
                    precision_score(label, sigmoid_val), recall_score(label, sigmoid_val),
                    accuracy_score(label, sigmoid_val),
                    f1_score(label, sigmoid_val))

            res = sorted(res.items(), key=lambda x: x[1][-1])
            max_res = res[-1]
            line+="{:.2f},{:.4f},{:.4f},{:.4f},{:.4f}\n".format(max_res[0],*max_res[1])

            op.write(line)

def draw_wrong():
    params = {
        #"entropy": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 4, "xmax": 7, "f": 0.5},  # 熵函数
        # "EAV": {"min_l":0.01,"max_l":0.99,"nums":99,"xmin":2,"xmax":10,"f":1},  # EAV点锐度算法函数
        # "SMD": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 2, "xmax": 9, "f": 0.5},  # SMD（灰度方差）函数
        # "SMD2": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 2, "xmax": 60, "f": 0.5},  # SMD2 （灰度方差乘积）函数
        # "variance": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 400, "xmax": 3600, "f": 1},  # 方差函数
        "tenengrad": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 5, "xmax": 50, "f": 1},  # Tenengrad 梯度函数
        "tenengrad2": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 7, "xmax": 35, "f": 0.5}, #Tenengrad2 原项目实现的Tenengrad 梯度函数
        # "vollath": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 430, "xmax": 3600, "f": 1},  # Vollath函数
        # "laplacian": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 2.5, "xmax": 7, "f": 11},  # Laplacian 梯度函数
        # "brenner": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 6, "xmax": 478, "f": 1},  # Brenner 梯度函数
        # "nrss": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 0.65, "xmax": 0.95, "f": 0.05},  # NRSS 梯度结构相似度
        # "energy": {"min_l": 0.01, "max_l": 0.99, "nums": 99, "xmin": 5, "xmax": 320, "f": 1},  # 能量梯度函数
        # "NR_IQA": {"min_l":0.01,"max_l":0.99,"nums":99,"xmin":-7,"xmax":-4,"f":0.5},  # No-Reference Image Quality Assessment  using Blur and Noise
        # "JPEQ": {"min_l":0.01,"max_l":0.99,"nums":99,"xmin":10,"xmax":12,"f":0.5},  # No-Reference Perceptual Quality Assessment of JPEG Compressed Images
        # "JPEQ2": {"min_l":0.01,"max_l":0.99,"nums":99,"xmin":4.998,"xmax":4.999,"f":0.001}  # No-Reference Image Quality Assessment forJPEG/JPEG2000 Coding
    }

    images_path = glob(os.path.join(datasets,"blur","images","*/*.JPG"))

    for key, value in params.items():
        csv_data, label = load_csv()
        data = csv_data[["images",key]]

        val = data[key].values
        images = list(data["images"].values)

        ###########################################################################
        max_f1 = 0
        max_pred = None
        max_th = 0
        for th in np.linspace(value["min_l"], value["max_l"], value["nums"]):
            tmp_val = sigmoid(val - np.mean(val))
            th_val = np.array(list(map(lambda x: 0 if x > th else 1, tmp_val)))

            f1 = f1_score(label,th_val)
            if f1>max_f1:
                max_f1 = f1
                max_pred = tmp_val
                max_th = th

        if not os.path.exists(os.path.join(root,"outputs",key)):
            os.makedirs(os.path.join(root,"outputs",key))

        pred = np.array(list(map(lambda x: 0 if x > max_th else 1, max_pred)))
        for image in images_path:
            filename = os.path.split(image)[-1]
            index= images.index(filename)
            image = cv2.imread(image)

            if label[index]^pred[index]:
                txt = "index = {}, th = {}".format(max_pred[index],max_th)
                cv2.putText(image, txt, (30, 30), cv2.FONT_HERSHEY_COMPLEX, 1.0, (0,0,255), 3)
                cv2.imwrite(os.path.join(root,"outputs",key,"sig_true_{}_pred_{}_{}".format(label[index],pred[index],filename)), image)
        ###########################################################################

        ###########################################################################
        max_f1 = 0
        max_pred = None
        max_th = 0
        for th in np.linspace(value["min_l"], value["max_l"], value["nums"]):
            tmp_val = min_max(val)
            th_val = np.array(list(map(lambda x: 0 if x > th else 1, tmp_val)))

            f1 = f1_score(label, th_val)
            if f1 > max_f1:
                max_f1 = f1
                max_pred = tmp_val
                max_th = th

        if not os.path.exists(os.path.join(root, "outputs", key)):
            os.makedirs(os.path.join(root, "outputs", key))
        pred = np.array(list(map(lambda x: 0 if x > max_th else 1, max_pred)))
        for image in images_path:
            filename = os.path.split(image)[-1]
            index = images.index(filename)
            image = cv2.imread(image)

            if label[index] ^ pred[index]:
                txt = "index = {}, th = {}".format(max_pred[index], max_th)
                cv2.putText(image, txt, (30, 30), cv2.FONT_HERSHEY_COMPLEX, 1.0, (0, 0, 255), 3)
                cv2.imwrite(os.path.join(root, "outputs", key,
                                         "mm_true_{}_pred_{}_{}".format(label[index], pred[index],filename)), image)
        ###########################################################################

        ###########################################################################
        max_f1 = 0
        max_pred = None
        max_th = 0
        for th in np.linspace(value["min_l"], value["max_l"], value["nums"]):
            tmp_val = map_min_max(val, xmin=value["xmin"], xmax=value["xmax"], f=value["f"])
            th_val = np.array(list(map(lambda x: 0 if x > th else 1, tmp_val)))

            f1 = f1_score(label, th_val)
            if f1 > max_f1:
                max_f1 = f1
                max_pred = tmp_val
                max_th = th

        if not os.path.exists(os.path.join(root, "outputs", key)):
            os.makedirs(os.path.join(root, "outputs", key))
        pred = np.array(list(map(lambda x: 0 if x > max_th else 1, max_pred)))
        for image in images_path:
            filename = os.path.split(image)[-1]
            index = images.index(filename)
            image = cv2.imread(image)

            if label[index] ^ pred[index]:
                txt = "index = {}, th = {}".format(max_pred[index], max_th)
                cv2.putText(image, txt, (30, 30), cv2.FONT_HERSHEY_COMPLEX, 1.0, (0, 0, 255), 3)
                cv2.imwrite(os.path.join(root, "outputs", key,
                                         "mmm_true_{}_pred_{}_{}".format(label[index], pred[index],filename)), image)
        ###########################################################################

if __name__ == '__main__':
    # csv_data,label = load_csv()
    # entropy(csv_data,label,min_l=0.01,max_l=0.99,nums=99)
    # EAV(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # SMD(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # SMD2(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # variance(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # tenengrad(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # tenengrad2(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # vollath(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # laplacian(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # brenner(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # nrss(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # energy(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    #NR_IQA(csv_data,label,min_l=0.01,max_l=0.99,nums=99)
    # JPEQ(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    # JPEQ2(csv_data, label,min_l=0.01,max_l=0.99,nums=99)
    max_index2csv()
    #draw_wrong()
